﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace Aribaccio
{
    /// <summary>
    /// 定义分页数据更新委托
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="curPageItems"></param>
    public delegate void PagerUpdatedDelegate<T>(List<T> curPageItems);
    /// <summary>
    /// 分页泛型数据集合
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public partial class PagerList<T> : NotificationObject
    {
        /// <summary>
        /// 定义委托事件
        /// </summary>
        public event PagerUpdatedDelegate<T>? PagerUpdated;

        private int _pageSize = 5;
        /// <summary>
        /// 每页显示数量
        /// </summary>
        public int PageSize { get { return this._pageSize; } set { if (value == this._pageSize) { return; } this._pageSize = value; base.NotifyPropertyChanged(() => PageSize); this.SetPageSize(_pageSize); } }

        private int _pageCount = 0;
        /// <summary>
        /// 总页数
        /// </summary>
        public int PageCount { get { return this._pageCount; } set { if (value == this._pageCount) { return; } if (value == 0) { value = 1; } this._pageCount = value; base.NotifyPropertyChanged(() => PageCount); } }

        private int _curPageIndex = 0;
        /// <summary>
        /// 当前页数
        /// </summary>
        public int CurPageIndex { get { return this._curPageIndex; } set { if (value == this._curPageIndex) { return; } this._curPageIndex = value; base.NotifyPropertyChanged(() => CurPageIndex); this.GotoPageOf(_curPageIndex); } }

        private ObservableCollection<T> _itemsSource;
        /// <summary>
        /// 数据集合
        /// </summary>
        public ObservableCollection<T> ItemsSource { get { return this._itemsSource; } set { this._itemsSource = value; base.NotifyPropertyChanged(() => ItemsSource); _curPageIndex = 0; this.CalculatePaging(); } }

        /// <summary>
        /// 构造函数
        /// </summary>
        public PagerList()
        {
            _itemsSource = new ObservableCollection<T>(new List<T>());
            _itemsSource.CollectionChanged += ItemsSourceOnCollectionChanged;
            CalculatePaging();
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="argPageSize"></param>
        public PagerList(int argPageSize)
        {
            _pageSize = argPageSize;
            _itemsSource = new ObservableCollection<T>(new List<T>());
            _itemsSource.CollectionChanged += ItemsSourceOnCollectionChanged;
            CalculatePaging();
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="argPageSize"></param>
        /// <param name="argSourceItems"></param>
        public PagerList(int argPageSize, List<T> argSourceItems)
        {
            _pageSize = argPageSize;
            _itemsSource = new ObservableCollection<T>(argSourceItems);
            _itemsSource.CollectionChanged += ItemsSourceOnCollectionChanged;
            CalculatePaging();
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="argPageSize"></param>
        /// <param name="argSourceItems"></param>
        public PagerList(int argPageSize, ObservableCollection<T> argSourceItems)
        {
            _pageSize = argPageSize;
            _itemsSource = argSourceItems;
            _itemsSource.CollectionChanged += ItemsSourceOnCollectionChanged;
            CalculatePaging();
        }

        /// <summary>
        /// 获取下一页数据集合
        /// </summary>
        /// <returns></returns>
        public List<T> NextPage()
        {
            return GotoPageOf(CurPageIndex + 1);
        }
        /// <summary>
        /// 获取上一页数据集合
        /// </summary>
        /// <returns></returns>
        public List<T> LastPage()
        {
            return GotoPageOf(CurPageIndex - 1);
        }
        /// <summary>
        /// 获取首页数据集合
        /// </summary>
        /// <returns></returns>
        public List<T> GotoStartPage()
        {
            return GotoPageOf(1);
        }
        /// <summary>
        /// 获取最后一页数据集合
        /// </summary>
        /// <returns></returns>
        public List<T> GotoEndPage()
        {
            return GotoPageOf(PageCount);
        }
        /// <summary>
        /// 获取当前页数据集合
        /// </summary>
        /// <param name="argPageIndex">当前页数索引值</param>
        /// <returns></returns>
        public List<T> GotoPageOf(int argPageIndex)
        {
            if (argPageIndex < 1) { argPageIndex = 1; }
            if (argPageIndex > PageCount) { argPageIndex = PageCount; }
            //设置更新当前页索引
            CurPageIndex = argPageIndex;
            //计算分页参数
            var skip = (CurPageIndex - 1) * PageSize;
            var maxIndex = CurPageIndex * PageSize - 1;
            if (maxIndex >= _itemsSource.Count) { maxIndex = _itemsSource.Count - 1; }
            //获取分页数据
            var list = _itemsSource != null && _itemsSource.Count > 0
                ? _itemsSource.ToList().GetRange(skip, maxIndex - skip + 1)
                : new List<T>();
            OnPagerUpdated(list);
            return list;
        }
        /// <summary>
        /// 设置每页显示数量
        /// </summary>
        /// <param name="argPageSize"></param>
        /// <returns></returns>
        public List<T> SetPageSize(int argPageSize)
        {
            PageSize = argPageSize;
            CalculatePaging();
            return GotoPageOf(1);
        }

        /// <summary>
        /// 绑定数据源集合改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ItemsSourceOnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
        {
            CalculatePaging();
            GotoPageOf(CurPageIndex);
        }
        /// <summary>
        /// 分页数据更新事件
        /// </summary>
        /// <param name="argCurPageItems"></param>
        private void OnPagerUpdated(List<T> argCurPageItems)
        {
            PagerUpdated?.Invoke(argCurPageItems);
        }
        /// <summary>
        /// 计算分页总页数
        /// </summary>
        private void CalculatePaging()
        {
            PageCount = _itemsSource != null ? (int)Math.Ceiling((double)_itemsSource.Count / PageSize) : 0;
        }
    }
}
